package cn.tedu.mall.order.service.impl;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.common.pojo.domain.CsmallAuthenticationInfo;
import cn.tedu.mall.common.restful.JsonPage;
import cn.tedu.mall.common.restful.ResponseCode;
import cn.tedu.mall.order.mapper.OmsOrderItemMapper;
import cn.tedu.mall.order.mapper.OmsOrderMapper;
import cn.tedu.mall.order.service.IOmsCartService;
import cn.tedu.mall.order.service.IOmsOrderService;
import cn.tedu.mall.order.utils.IdGeneratorUtils;
import cn.tedu.mall.pojo.order.dto.OrderAddDTO;
import cn.tedu.mall.pojo.order.dto.OrderItemAddDTO;
import cn.tedu.mall.pojo.order.dto.OrderListTimeDTO;
import cn.tedu.mall.pojo.order.dto.OrderStateUpdateDTO;
import cn.tedu.mall.pojo.order.model.OmsCart;
import cn.tedu.mall.pojo.order.model.OmsOrder;
import cn.tedu.mall.pojo.order.model.OmsOrderItem;
import cn.tedu.mall.pojo.order.vo.OrderAddVO;
import cn.tedu.mall.pojo.order.vo.OrderDetailVO;
import cn.tedu.mall.pojo.order.vo.OrderListVO;
import cn.tedu.mall.product.service.order.IForOrderSkuService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

//准备被远程调用
@DubboService
@Service
@Slf4j
public class OmsOrderServiceImpl implements IOmsOrderService {
    @DubboReference
    private IForOrderSkuService dubboSkuService;
    @Autowired
    private IOmsCartService omsCartService;
    @Autowired
    private OmsOrderMapper omsOrderMapper;
    @Autowired
    private OmsOrderItemMapper omsOrderItemMapper;
    // 启用seata支持的分布式事务，使删库存，删购物车。。等一系列操作同时成功
    //@GlobalTransactional()
    @Override
    public OrderAddVO addOrder(OrderAddDTO orderAddDTO) {
        /*----------------------收集信息--------------------------------------------*/
        OmsOrder order = new OmsOrder();
        // 其中addDTO已经包含了订单项，所以order也包含了订单项
        BeanUtils.copyProperties(orderAddDTO,order);
        loadOrder(order);
        List<OrderItemAddDTO> orderItems=orderAddDTO.getOrderItems();
        if(orderItems==null||orderItems.isEmpty()){
            throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST,"订单中至少要包含一件商品");
        }
        //orderItems的元素转换为OmsOrderItem
        List<OmsOrderItem> omsOrderItems=new ArrayList<>();
        for (OrderItemAddDTO addDTO:orderItems){
            OmsOrderItem omsOrderItem=new OmsOrderItem();
            BeanUtils.copyProperties(addDTO,omsOrderItem);
            //小类缺属性➡去leaf中获取
            Long itemId=IdGeneratorUtils.getDistributeId("order_item");
            omsOrderItem.setId(itemId);
            omsOrderItem.setOrderId(order.getId());
            omsOrderItems.add(omsOrderItem);
        /*----------------------操作数据库--------------------------------------------*/
            Long skuId=omsOrderItem.getSkuId();
            // 删库存
            int num=dubboSkuService.reduceStockNum(skuId,omsOrderItem.getQuantity());
            if (num==0){
                log.error("商品库存不足，skuId:{}",skuId);
            }
            // 删购物车
            OmsCart omsCart=new OmsCart();
            omsCart.setUserId(order.getUserId());
            omsCart.setSkuId(omsOrderItem.getSkuId());
            omsCartService.removeUserCarts(omsCart);
        }
        // 新增订单
        omsOrderMapper.insertOrder(order);
        // 新增订单项
        omsOrderItemMapper.insertOrderItemList(omsOrderItems);
        /*----------------------收集返回值--------------------------------------------*/
        OrderAddVO addVO=new OrderAddVO();
        addVO.setId(order.getId());
        addVO.setSn(order.getSn());
        addVO.setCreateTime(order.getGmtCreate());
        addVO.setPayAmount(order.getAmountOfActualPay());

        return addVO;
    }

    @Override
    public void updateOrderState(OrderStateUpdateDTO orderStateUpdateDTO) {
        OmsOrder order=new OmsOrder();
        BeanUtils.copyProperties(orderStateUpdateDTO,order);
        omsOrderMapper.updateOrderById(order);
    }

    // 查询一定时间内的订单
    @Override
    public JsonPage<OrderListVO> listOrdersBetweenTimes(OrderListTimeDTO orderListTimeDTO) {
        validateTimes(orderListTimeDTO);
        PageHelper.startPage(orderListTimeDTO.getPage(),orderListTimeDTO.getPageSize());
        orderListTimeDTO.setUserId(getUserId());
        List<OrderListVO> list=omsOrderMapper.selectOrdersBetweenTimes(orderListTimeDTO);
        return JsonPage.restPage(new PageInfo<>(list));
    }

    private void validateTimes(OrderListTimeDTO orderListTimeDTO) {
        LocalDateTime start=orderListTimeDTO.getStartTime();
        LocalDateTime end=orderListTimeDTO.getEndTime();
        if(start==null || end==null){
            start=LocalDateTime.now().minusMonths(1);
            end=LocalDateTime.now();
            orderListTimeDTO.setStartTime(start);
            orderListTimeDTO.setEndTime(end);
        }else{
            //  北京时间转为格林威治时间（加的是时区）  1970.1.1到现在经历的所有毫秒数（时间偏移量）
            if(end.toInstant(ZoneOffset.of("+8")).toEpochMilli()<start.toInstant(ZoneOffset.of("+8")).toEpochMilli()){
                throw new CoolSharkServiceException(ResponseCode.BAD_REQUEST,"结束时间应大于开始时间!");
            }
        }
    }

    @Override
    public OrderDetailVO getOrderDetail(Long id) {
        return null;
    }

    private void loadOrder(OmsOrder order){
        //“order”对应leaf_alloc表中的biz_tag字段
        Long id =IdGeneratorUtils.getDistributeId("order");
        order.setUserId(id);
        order.setSn(UUID.randomUUID().toString());
        if(order.getUserId()==null){
            order.setUserId(getUserId());
        }
        if(order.getState()==null){
            order.setState(0);
        }
        LocalDateTime now =LocalDateTime.now();
        // 避免时间差，不给create赋值数据库自己也会赋，但是就无法确定
        // 订单到底算哪一天的（时间差导致的跨年跨天问题）
        order.setGmtCreate(now);
        order.setGmtOrder(now);
        order.setGmtModified(now);
        // BigDecimal:防计算误差
        BigDecimal price=order.getAmountOfOriginalPrice();
        // 运费
        BigDecimal freight=order.getAmountOfFreight();
        BigDecimal discount=order.getAmountOfDiscount();
        BigDecimal actualPay=price.subtract(discount).add(freight);
        order.setAmountOfActualPay(actualPay);

    }

    /*以下为粘贴OmsCartServiceImpl内容*/
    public CsmallAuthenticationInfo getUserInfo() {
        UsernamePasswordAuthenticationToken authenticationToken=
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        if(authenticationToken==null){
            throw new CoolSharkServiceException(ResponseCode.UNAUTHORIZED,"您还未登录");
        }
        CsmallAuthenticationInfo csmallAuthenticationInfo=(CsmallAuthenticationInfo) authenticationToken.getCredentials();

        return csmallAuthenticationInfo;
    }
    public Long getUserId() {
        return getUserInfo().getId();
    }
}
